package pe.com.casadesign.dao.impl;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;

import javax.sql.DataSource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.jdbc.core.simple.SimpleJdbcCall;
import org.springframework.stereotype.Repository;

import pe.com.casadesign.dao.ParametroDAO;
import pe.com.casadesign.domain.CorreoModulo;
import pe.com.casadesign.domain.Item;
import pe.com.casadesign.domain.ListaItem;
import pe.com.casadesign.domain.ListaParametro;
import pe.com.casadesign.domain.Parametro;
import pe.com.casadesign.domain.Tienda;

/**
 * Implementacion de ParametroDAO.
 * 
 * @author Pedro Vera
 * 
 */
@Repository
public class ParametroDAOImpl implements ParametroDAO {
	private static final Logger logger = LoggerFactory.getLogger(ParametroDAOImpl.class);
	
	// Nombre Procedimientos Almacenados
	private static String SP_LISTAR_PARAMETRO = "SP_LISTAR_PARAMETRO";
	private static String SP_ACTUALIZAR_PARAMETRO = "SP_ACTUALIZAR_PARAMETRO";
	private static String SP_OBTENER_HORAACTUAL = "SP_OBTENER_HORAACTUAL";
	
	// Parametros de Entrada
	private static String PARAM_CODIGO = "p_codigo";
	private static String PARAM_VALOR = "p_Valor";
	
	// Parametros de Salida
	private static String CODIGO = "CODIGO";
	private static String DESCRIPCION = "DESCRIPCION";
	private static String VALOR = "VALOR";
	private static String FECHAREGISTRO = "FECHAREGISTRO";
	
	private static String LISTADO = "LISTADO";
	
	private static String TOTAL_FILAS_AFECTADAS = "#update-count-1";
	
	private JdbcTemplate jdbcTemplate;

	@Autowired
    public void setDataSource(DataSource dataSource)
    {
        this.jdbcTemplate = new JdbcTemplate(dataSource);
    }
	
	@Override
	public ListaParametro listarParametro() {
		logger.info("listarParametro");

		// Instanciando variable para llamado de SP
	    SimpleJdbcCall llamarSP = new SimpleJdbcCall(jdbcTemplate).withProcedureName(SP_LISTAR_PARAMETRO).
	    						  returningResultSet(LISTADO, new RowMapper<Parametro>(){
									@Override
									public Parametro mapRow(final ResultSet rs, final int numRow) throws SQLException
								    {
								        final Parametro parametro = new Parametro();
								        parametro.setCodigo(rs.getInt(CODIGO));
								        parametro.setDescripcion(rs.getString(DESCRIPCION));
								        parametro.setValor(rs.getString(VALOR));
								        parametro.setFechaRegistro(rs.getDate(FECHAREGISTRO).toString());
								        
								        return parametro;
								    }
	    						  }
								);


	    // Establecer parametros y ejecutar SP
        Map<String,Object> data = llamarSP.execute();

        // Obteniendo lista generada de ejecutar SP
		@SuppressWarnings("unchecked")
		List<Parametro> listaParametro = (List<Parametro>)data.get(LISTADO);
        
		// Instanciando objeto ListaParametro
		ListaParametro listaParametroResultado = new ListaParametro();
        // Estableciendo resultado al objeto listaParametroResultado
		listaParametroResultado.setLista(listaParametro);
        
        if (logger.isDebugEnabled() && listaParametroResultado != null)
        {
            logger.debug("size=" + listaParametroResultado.size());
        }
        return listaParametroResultado;
	}

	@Override
	public boolean actualizarParametros(ListaParametro listaParametro) {
		logger.info("actualizarParametros");
		
		int totalRegistrosAfectado = 0;
	    
	    // Instanciando variable para llamado de SP
	    SimpleJdbcCall llamarSP = new SimpleJdbcCall(jdbcTemplate).withProcedureName(SP_ACTUALIZAR_PARAMETRO);
	    
	    for (Parametro parametro : listaParametro.getLista()){
	    	 // Estableciendo parametros de entrada al SP
		    SqlParameterSource parametros = new MapSqlParameterSource()
		    								.addValue(PARAM_CODIGO, parametro.getCodigo())
		    								.addValue(PARAM_VALOR, parametro.getValor());
		    
		    // Establecer parametros y ejecutar SP
		    Map<String,Object> data = llamarSP.execute(parametros);
		    
		    // Obteniendo el total de filas afectadas al ejecutar SP
		    totalRegistrosAfectado += (Integer) data.get(TOTAL_FILAS_AFECTADAS);
	    }
	    
		return totalRegistrosAfectado>0;
	}

	@Override
	public Parametro obtenerHoraActual() {
		logger.info("obtenerHoraActual");

		// Instanciando variable para llamado de SP
	    SimpleJdbcCall llamarSP = new SimpleJdbcCall(jdbcTemplate).withProcedureName(SP_OBTENER_HORAACTUAL).
	    						  returningResultSet(LISTADO, new RowMapper<Parametro>(){
									@Override
									public Parametro mapRow(final ResultSet rs, final int numRow) throws SQLException
								    {
								        final Parametro parametro = new Parametro();
								        parametro.setCodigo(rs.getInt(CODIGO));
								        parametro.setDescripcion(rs.getString(DESCRIPCION));
								        parametro.setValor(rs.getString(VALOR));
								        parametro.setFechaRegistro(rs.getDate(FECHAREGISTRO).toString());
								        
								        return parametro;
								    }
	    						  }
								);


	    // Establecer parametros y ejecutar SP
        Map<String,Object> data = llamarSP.execute();

        // Obteniendo lista generada de ejecutar SP
		@SuppressWarnings("unchecked")
		List<Parametro> listaParametro = (List<Parametro>)data.get(LISTADO);
        
		// Declarando objeto Parametro Obtenido
		Parametro parametroObtenido = null;
		

        if (logger.isDebugEnabled() && listaParametro != null)
        {
            logger.debug("size=" + listaParametro.size());
        }
        
        if (listaParametro != null && listaParametro.size()>0){
 			// Obteniendo el primer elemento de la lista de CorreoModulo
        	parametroObtenido = listaParametro.get(0);
 		}
        
        return parametroObtenido;
	}
	
}
